#include "socketmanager.h"
#include <QDebug>
#include <QFile>
#include <QSslCertificate>
#include <QSslConfiguration>

SocketManager::SocketManager(QObject *parent)
    : QObject(parent),
    sslSocket(new QSslSocket(this))
{
    // 连接 SSL 错误信号到槽函数
    connect(sslSocket, &QSslSocket::sslErrors, this, &SocketManager::onSslErrors);
    // 连接读取数据信号到槽函数
    connect(sslSocket, &QSslSocket::readyRead, this, &SocketManager::onReadyRead);
    // 连接连接状态变化信号到槽函数
    connect(sslSocket, &QSslSocket::stateChanged, this, &SocketManager::onStateChanged);
}

void SocketManager::connectToServer(const QString &host, quint16 port) {
    qDebug() << "Attempting to connect to server:" << host << port;
    sslSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
    sslSocket->connectToHostEncrypted(host, port);
    if (!sslSocket->waitForEncrypted(5000)) {
        emit connectionFailed("网络异常，请重试");
    }
}

void SocketManager::sendData(const QByteArray &data) {
    if (sslSocket->state() == QSslSocket::ConnectedState) {
        sslSocket->write(data);
        sslSocket->flush();
    } else {
        emit connectionFailed("未连接到服务器，无法发送数据");
    }
}

void SocketManager::loadCaCertificate(const QString &certFilePath) {
    QFile certFile(certFilePath);
    if (certFile.open(QIODevice::ReadOnly)) {
        QSslCertificate cert(&certFile, QSsl::Pem);
        QList<QSslCertificate> certs;
        certs.append(cert);
        QSslConfiguration sslConfig = sslSocket->sslConfiguration();
        sslConfig.setCaCertificates(certs);
        sslSocket->setSslConfiguration(sslConfig);
    } else {
        qDebug() << "Failed to load CA certificate from" << certFilePath;
    }
}

void SocketManager::onSslErrors(const QList<QSslError> &errors) {
    foreach (const QSslError &error, errors) {
        qWarning() << "SSL Error:" << error.errorString();
    }
    sslSocket->ignoreSslErrors(); // 忽略 SSL 错误，实际应用中需要根据情况处理
}

void SocketManager::onReadyRead() {
    QByteArray data = sslSocket->readAll();
    emit dataReceived(data);
}

void SocketManager::onStateChanged(QAbstractSocket::SocketState state) {
    switch (state) {
    case QAbstractSocket::UnconnectedState:
        qDebug() << "Socket is unconnected";
        break;
    case QAbstractSocket::HostLookupState:
        qDebug() << "Looking up host...";
        break;
    case QAbstractSocket::ConnectingState:
        qDebug() << "Connecting to host...";
        break;
    case QAbstractSocket::ConnectedState:
        qDebug() << "Connected to host";
        break;
    case QAbstractSocket::BoundState:
        qDebug() << "Socket is bound";
        break;
    case QAbstractSocket::ListeningState:
        qDebug() << "Socket is listening";
        break;
    case QAbstractSocket::ClosingState:
        qDebug() << "Socket is closing";
        break;
    }
}
